/**
 * 
 */
package com.et114.components.jcaptcha;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.acegisecurity.captcha.CaptchaServiceProxy;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

/**
 * @author guanhw
 *
 */
public class CaptchaValidationProcessingFilter extends HttpServlet implements  Filter {
	private static final long serialVersionUID = -5320261556625062783L;

	//~ Static fields/initializers =====================================================================================

    protected static final Log logger = LogFactory.getLog(CaptchaValidationProcessingFilter.class);
    private ApplicationContext ctx;
    //~ Instance fields ================================================================================================

    private CaptchaServiceProxy captchaService;
    private String captchaValidationParameter = "j_captcha_response";
    private String captchaValidationFto = "login?logincode=error" ;

    //~ Methods ========================================================================================================

    public void afterPropertiesSet() throws Exception {
        if (this.captchaService == null) {
            throw new IllegalArgumentException("CaptchaServiceProxy must be defined ");
        }

        if ((this.captchaValidationParameter == null) || "".equals(captchaValidationParameter)) {
            throw new IllegalArgumentException("captchaValidationParameter must not be empty or null");
        }
    }

    /**
     * Does nothing. We use IoC container lifecycle services instead.
     */
    public void destroy() {}

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
        throws IOException, ServletException {
    	HttpServletResponse httpResponse = ( HttpServletResponse )  response ; 
        String captchaResponse = request.getParameter( captchaValidationParameter );
		if ((request != null) && request instanceof HttpServletRequest
				&& (captchaResponse != null)) {
            logger.debug( "captcha validation parameter found");

            // validate the request against CaptchaServiceProxy
            boolean valid = false;

            logger.debug( "try to validate" );

            //get session
            HttpSession session = ((HttpServletRequest) request).getSession();

            if (session != null) {
                String id = session.getId();
                //init captchaService
				ctx = getContext( ( HttpServletRequest )request );
				captchaService = ( CaptchaServiceProxy )ctx.getBean( "captchaService" ) ;
                valid = captchaService.validateReponseForId(id, captchaResponse);
                logger.info(  "captchaServiceProxy says : request is valid = " + valid);
                if (valid) {
                    chain.doFilter(request, response);
                } else {
                	httpResponse.sendRedirect( captchaValidationFto ) ; 
                	return;
                }
            } else {
                logger.debug("no session found, user don't even ask a captcha challenge");
            }
        } else {
            chain.doFilter(request, response);

        }
    }

    public CaptchaServiceProxy getCaptchaService() {
        return captchaService;
    }

    public String getCaptchaValidationParameter() {
        return captchaValidationParameter;
    }

    /**
     * Does nothing. We use IoC container lifecycle services instead.
     *
     * @param filterConfig ignored
     *
     * @throws ServletException ignored
     */
    public void init(FilterConfig filterConfig) throws ServletException {
    
    	if ( filterConfig.getInitParameter( "captchaValidationParameter" ) != null )
    		captchaValidationParameter = filterConfig.getInitParameter( "captchaValidationParameter" ) ;
    	
    	if ( filterConfig.getInitParameter( "captchaValidationFto" )  != null ) 
    		captchaValidationFto = filterConfig.getInitParameter( "captchaValidationFto" ) ;
    	
    }

    public void setCaptchaService(CaptchaServiceProxy captchaService) {
        this.captchaService = captchaService;
    }

    public void setCaptchaValidationParameter(String captchaValidationParameter) {
        this.captchaValidationParameter = captchaValidationParameter;
    }
    
	public String getCaptchaValidationFto() {
		return captchaValidationFto;
	}

	public void setCaptchaValidationFto(String captchaValidationFto) {
		this.captchaValidationFto = captchaValidationFto;
	}

	protected ApplicationContext getContext(HttpServletRequest httpRequest) {
        return WebApplicationContextUtils.getRequiredWebApplicationContext(httpRequest.getSession().getServletContext());
    }    
}
